package com.hqyj.hjy.config;


import com.hqyj.hjy.mapper.UserMapper;
import com.hqyj.hjy.pojo.Role;
import com.hqyj.hjy.pojo.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

// 配置shiro认证和授权
public class MyRealm extends AuthorizingRealm {

    // 注入接口
    @Autowired
    private UserMapper userMapper;

    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 把登录的用户信息获取到
        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("loginUser");
        // 取出登录用户信息中的角色信息
        List<Role> roleList = user.getRoles();
        // 创建set集合，用来存角色信息
        Set<String> roleSet = new HashSet<>();
        // 判断角色信息是否为null
        if (roleList != null){
            // 遍历roleList，获取到每一个角色名称
            for (Role role : roleList) {
                // 可以把角色信息存入 set 集合
                roleSet.add(role.getRoleName());
            }
        }
        // 创建SimpleAuthorizationInfo对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 调用SimpleAuthorizationInfo对象中的addRoles方法，把当前用户的角色信息存入进入
        info.addRoles(roleSet);

        return info;


    }

    // 认证：判断当前用户是否能够登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取当前登录的用户名
        String username = (String) token.getPrincipal();
        // 把用户传入数据库查询用户信息
        User user = userMapper.selectUserByUsername(username);
        // 判断查询出来的用户是否为null
        if (user == null){
            // 如果查询出来的用户为null，表示数据库中没有该用户信息
            throw new UnknownAccountException();
        }
        // 如果查询出来的用户存在，就把当前用户信息存入session中
        SecurityUtils.getSubject().getSession().setAttribute("loginUser",user);
        // 获取盐
        SimpleHash hashedSalt = new SimpleHash("MD5", user.getUsername());
        ByteSource salt = ByteSource.Util.bytes(hashedSalt.toString());
        // 返回：参数：1、用户名 2、密码 3、盐 4、getName()方法，realm名称
        return new SimpleAuthenticationInfo(username,user.getPassword(),salt,getName());

    }
}
